/* @flow */
import { createAction, handleActions, type ActionType } from 'redux-actions';
import produce from 'immer';
import * as AuthApi from 'lib/api/auth';
import { redirect_uri } from 'lib/socialAuth';
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects';
import { createSagaActionType, createSagaAction, REQUEST, SUCCESS, FAILURE } from '../sagaUtils';
import * as social from 'lib/socialAuth';
//Request
//Success
//Failure
/* ACTION TYPE */
const AUTH_FAILURE = 'auth/AUTH_FAILURE';
const SET_EMAIL_INPUT = 'auth/SET_EMAIL_INPUT';
const SET_EMAIL_SENDING = 'auth/SET_EMAIL_SENDING';
const SEND_AUTH_EMAIL = createSagaActionType('auth/SEND_AUTH_EMAIL');
const EMAIL_REGISTER = createSagaActionType('auth/LOCAL_REGISTER');
const RIGISTER_FORM_CHANGE = 'auth/RIGISTER_FORM_CHANGE';
const SEND_CODE = createSagaActionType('auth/SEND_CODE');
const SOCAIL_CODE_LOGIN = createSagaActionType('auth/SOCAIL_CODE_LOGIN');
const SOCAIL_CODE_REGIST = createSagaActionType('auth/SOCAIL_CODE_REGIST');

/* ACTION PAYLOAD */
type authEmailPayload = {
    isUser: number,
    provider: string
};
type sendCodePayload = {
    windowName: string,
    code: string
};
type socialCodeLoginPayload = {
    windowName: number,
    provider: string
};
type codeLoginSuccessPayload = {
    user: {
        id: string,
        username: string,
        displayName: string,
        thumbnail?: ?string
    },
    token: string
};
export const actionCreators = {
    authFailure: createAction(AUTH_FAILURE, (payload: string) => payload),
    setEmailInput: createAction(SET_EMAIL_INPUT, (value: string) => value),
    setEmailSending: createAction(SET_EMAIL_SENDING),
    sendAuthEmailRequest: createAction(SEND_AUTH_EMAIL.REQUEST, (value: string) => value),
    sendAuthEmailSuccess: createAction(
        SEND_AUTH_EMAIL.SUCCESS,
        (payload: authEmailPayload) => payload
    ),
    sendAuthEmailFailure: createAction(SEND_AUTH_EMAIL.FAILURE, (message: string) => message),
    sendCodeRequest: createAction(SEND_CODE.REQUEST, (payload: sendCodePayload) => payload),
    sendCodeSuccess: createAction(SEND_CODE.SUCCESS, (payload: sendCodePayload) => payload),
    sendCodeFailure: createAction(SEND_CODE.FAILURE, (payload: string) => payload),
    socailCodeLoginRequest: createAction(
        SOCAIL_CODE_LOGIN.REQUEST,
        (payload: codeLoginPayload) => payload
    ),
    socailCodeLoginSuccess: createAction(
        SOCAIL_CODE_LOGIN.SUCCESS,
        (payload: codeLoginSuccessPayload) => payload
    ),
    socailCodeLoginFailure: createAction(SOCAIL_CODE_LOGIN.FAILURE, (message: string) => message),
    socailCodeRegistRequest: createAction(
        SOCAIL_CODE_REGIST.REQUEST,
        (payload: codeLoginPayload) => payload
    ),
    socailCodeRegistSuccess: createAction(
        SOCAIL_CODE_REGIST.SUCCESS,
        (payload: codeLoginSuccessPayload) => payload
    ),
    socailCodeRegistFailure: createAction(SOCAIL_CODE_REGIST.FAILURE, (message: string) => message)
};

/* State Types */
export type UserData = {
    id: string,
    email: string,
    displayName: string,
    thumbnail?: ?string
};
export type SocialAuthResult = ?{
    provider: string,
    accessToken: string
};

export type Auth = {
    email: string,
    sending: boolean,
    sentEmail: boolean,
    isUser: boolean,
    isSocial: boolean,
    user: ?UserData,
    processed: boolean,
    registerForm: {
        displayName: string,
        email: string
    },
    registerToken: string,
    accessToken: string,
    socialType: string,
    exists: boolean,
    message: string
};

const initialState: Auth = {
    email: '',
    sending: false,
    sentEmail: false,
    isUser: false,
    isSocial: false,
    user: null,
    processed: false,
    registerForm: null,
    registerToken: '',
    accessToken: '',
    socialType: '',
    exists: false,
    message: ''
};

export default handleActions(
    {
        [SET_EMAIL_INPUT]: (state, action: SetEmailInputAction) => {
            return produce(state, draft => {
                if (!action || !draft) return;
                draft.email = action.payload;
            });
        },
        [SET_EMAIL_SENDING]: state => {
            return produce(state, draft => {
                draft.sending = true;
            });
        },
        [SEND_AUTH_EMAIL.SUCCESS]: (state, action: SendVerificationEmailAction) => {
            return produce(state, draft => {
                if (!action || !draft) return;
                draft.provider = 'email';
                draft.isUser = action.payload.isUser === 0 ? false : true;
                draft.sending = false;
                draft.sentEmail = true;
            });
        },
        [SEND_AUTH_EMAIL.FAILURE]: (state, action: SendVerificationEmailAction) => {
            return produce(state, draft => {
                if (!action || !draft) return;
                draft.message = action.payload;
                draft.sending = false;
            });
        },
        [AUTH_FAILURE]: (state, action) => {
            return produce(state, draft => {
                if (!action || !draft) return;
                draft.message = action.payload;
            });
        }
    },
    initialState
);
function* sentAuthEmail(action: SendAuthEmailRequestAction) {
    try {
        yield put({ type: SET_EMAIL_SENDING });
        console.log(action.payload);
        const ret = yield AuthApi.sendAuthEmail(action.payload.provider, action.payload.windowName);
        yield put({
            type: SEND_AUTH_EMAIL.SUCCESS,
            payload: {
                isUser: ret.data.data.isUser,
                provider: 'email'
            }
        });
    } catch (e) {
        yield put({
            type: AUTH_FAILURE,
            payload: {
                message: e.message
            }
        });
    }
}
function* socialCodeRegist(action) {
    try {
    } catch (e) {}
}
function* socialCodeLogin(action) {
    try {        
        const ret = yield AuthApi.verifySocial(
            action.payload.windowName,
            action.payload.provider,
            redirect_uri
        );
        if(!ret.data.data.isUser) call(socialCodeRegist,)
        yield put({
            type: SOCAIL_CODE_LOGIN.SUCCESS,
            payload: {
                isUser: ret.data.data.isUser
            }
        });
    } catch (e) {
        yield put({
            type: AUTH_FAILURE,
            payload: {
                message: e.message
            }
        });
    }
}
function* sendCodeSaga(action) {
    try {
        console.log(action);
        AuthApi.sendCode(action.payload.windowName, action.payload.code);
    } catch (e) {
        yield put({
            type: AUTH_FAILURE,
            payload: {
                message: e.message
            }
        });
    }
}
export function* RootSaga() {
    console.log('auth Hello Sagas!');
    yield takeEvery(SEND_AUTH_EMAIL.REQUEST, sentAuthEmail);
    yield takeEvery(SOCAIL_CODE_LOGIN.REQUEST, socialCodeLogin);
    yield takeEvery(SEND_CODE.REQUEST, sendCodeSaga);
}
